<template>
    <div class="freedom-container" @contextmenu.prevent>
        <vue-draggable-resizable
                v-for="(item,index) in Items"
                :w="item.style.w"
                :h="item.style.h"
                :y="item.style.y"
                :x="item.style.x"
                :z="item.style.z"
                :active.sync="item.active"
                :parent="true"
                :min-width="10"
                :min-height="10"
                :snap="true"
                :snapTolerance="2"
                :index="index"
                :multiple="true"
                classNameIgnoreDeactivated="menu-item"
                :style="{background:item.style.backgroundColor}"
                @refLineParams="getRefLineParams"
                @dragging="(x, y) => onDragging(index, x, y)"
                @dragstop="(x, y) => onDragstop(index, x, y)"
                @resizing="(x,y,w,h) => onResizstop(index,x,y,w,h)"
                @activated="onActivated"
                @deactivated="onActivated"
                >
        </vue-draggable-resizable>

        <!--辅助线-->
        <span class="ref-line"
              v-for="item in AuxiliaryLines"
              :key="item.id"
              v-show="item.display"
              :style="item"/>
        <!--辅助线END-->
    </div>
</template>

<script>

    import {addEvent, removeEvent,getComputedSize } from '../utils/dom'
    import VueDraggableResizable from './vue-draggable-resizable'
    import './vue-draggable-resizable.css'
    export default {
        name: "freedom-container",
        components: {
            VueDraggableResizable,
        },
        data() {
            return {
                AuxiliaryLines:[],
                Items:[
                    {
                        active:false,
                        style:{
                            x:0,
                            y:50,
                            w:100,
                            h:120,
                            z:0,
                            backgroundColor:'rgb(239, 154, 154)',
                        },
                    },
                    {
                        active:false,
                        style:{
                            x:50,
                            y:300,
                            w:150,
                            h:100,
                            z:0,
                            backgroundColor:'rgb(129, 212, 250)',
                        },
                    },
                    {
                        active:false,
                        style:{
                            x:160,
                            y:100,
                            w:100,
                            h:100,
                            z:0,
                            backgroundColor:'rgb(174, 213, 129)',
                        },
                    }
                ],
                WillCopyItems:[],
            }
        },
        mounted: function () {
            addEvent(document.documentElement, 'keydown', this.onKeyDown);
            this.$bus.$on('topbar-menuitem',this.topbarMenuItemAction)
        },
        beforeDestroy:function() {
            this.$bus.$off('topbar-menuitem');
            removeEvent(document.documentElement, 'keydown', this.onKeyDown);
        },

        methods: {
            // 辅助线回调事件
            getRefLineParams(params) {
                let id = 0;
                let auxiliaryLines = [];
                auxiliaryLines.push(...params.vLine.map(item => {
                    return {
                        top:item.origin,
                        left:item.position,
                        height:item.lineLength,
                        display:item.display,
                        id:++id,
                    }
                }));
                auxiliaryLines.push(...params.hLine.map(item => {
                    return {
                        top:item.position,
                        left:item.origin,
                        width:item.lineLength,
                        display:item.display,
                        id:++id,
                    }
                }));

                this.AuxiliaryLines = auxiliaryLines;
            },

            //鼠标单击画板，不支持触摸屏
            // desktopMouseDownLeft(e){

            // },

            //改变尺寸
            onResizstop(index,x,y,w,h){
                this.Items[index].style.x = x;
                this.Items[index].style.y = y;
                this.Items[index].style.w = w;
                this.Items[index].style.h = h;
            },
            //拖动中
            onDragging(index,x,y){
                let [width,height] = getComputedSize(this.$el);

                let target = this.Items[index];
                let deltaX = x - target.style.x;
                let deltaY = y - target.style.y;
                this.Items.forEach((item,idx)=>{
                    if (item.active){
                        //计算偏移量和可活动的尺寸
                        item.style.x = Math.max(0,Math.min(width - item.style.w,item.style.x + deltaX));
                        item.style.y = Math.max(0,Math.min(height - item.style.h,item.style.y + deltaY));
                    }
                });
            },

            //停止拖动
            onDragstop(index, x, y){
            },

            //点击键盘
            onKeyDown(event){
                let e = event || window.event;
                let shiftKey = e.shiftKey;

                if (e.keyCode === 39){
                    this.Items.filter(item=>item.active).forEach(item=>{item.style.x += 1 * shiftKey ? 10 : 1;})    //右
                }else if (e.keyCode === 40){
                    this.Items.filter(item=>item.active).forEach(item=>{item.style.y += 1 * shiftKey ? 10 : 1;})    //上
                }else if (e.keyCode === 38){
                    this.Items.filter(item=>item.active).forEach(item=>{item.style.y -= 1 * shiftKey ? 10 : 1;})    //下
                }else if (e.keyCode === 37){
                    this.Items.filter(item=>item.active).forEach(item=>{item.style.x -= 1 * shiftKey ? 10 : 1;})    //左
                }else if (e.ctrlKey && e.keyCode === 67){
                    this.WillCopyItems = JSON.parse(JSON.stringify(this.Items.filter(item=>item.active)));  //复制
                }else if (e.ctrlKey && e.keyCode === 16){
                    this.WillCopyItems = JSON.parse(JSON.stringify(this.Items.filter(item=>item.active)));  //剪切
                }else if (e.ctrlKey && e.keyCode === 86){
                    //粘贴
                    // let [width,height] = getComputedSize(this.$el);
                    this.Items.push(...JSON.parse(JSON.stringify(this.WillCopyItems.map(item=>{
                        let r = {...item};
                        r.active = false;
                        r.style.x += 10;
                        r.style.y += 10;
                        return r;
                    }))));
                }else if(e.keyCode === 8){
                    this.Items = this.Items.filter(item=>!item.active);
                }
            },

            //点击激活
            onActivated(){

            },

            //点击顶部工具栏通知
            topbarMenuItemAction(action){
                let actives = this.Items.filter(item=>item.active);
                //TODO:此处需要对actives 排序

                if (action === 'alignTop'){
                    if (actives.length > 1){
                        let minY = Math.min(...actives.map(item=>item.style.y));
                        actives.forEach(item=>{
                            item.style.y = minY;
                        })
                    }
                }else if (action === 'alignBottom'){
                    if (actives.length > 1){
                        let maxY = Math.max(...actives.map(item=>item.style.y + item.style.h));
                        actives.forEach(item=>{
                            item.style.y = maxY - item.style.h;
                        })
                    }
                }else if (action === 'alignLeft'){
                    if (actives.length > 1){
                        let minX = Math.min(...actives.map(item=>item.style.x));
                        actives.forEach(item=>{
                            item.style.x = minX;
                        })
                    }
                }else if (action === 'alignRight'){
                    if (actives.length > 1){
                        let maxX = Math.max(...actives.map(item=>item.style.x + item.style.w));
                        actives.forEach(item=>{
                            item.style.x = maxX - item.style.w;
                        })
                    }
                }else if (action === 'horizontalCenter'){
                    if (actives.length > 1){
                        let first = actives[0];
                        let centerX = first.style.x + first.style.w / 2;
                        actives.forEach((item,index)=>{
                            if(index > 0){
                                item.style.x = centerX - item.style.w / 2;
                            }
                        });
                    }
                }else if (action === 'verticalCenter'){
                    if (actives.length > 1){
                        let first = actives[0];
                        let centerY = first.style.y + first.style.h / 2;
                        actives.forEach((item,index)=>{
                            if(index > 0){
                                item.style.y = centerY - item.style.h / 2;
                            }
                        });
                    }
                }else if (action === 'horizontalSpace'){
                    if (actives.length > 1) {
                        let [width,height] = getComputedSize(this.$el);
                        let sumWidth = actives.reduce((sum, item) => sum + item.style.w, 0);
                        let space = (width - sumWidth) / (actives.length - 1);
                        let lastX = 0;
                        actives.forEach((item)=>{
                            item.style.x = lastX;
                            lastX = item.style.x + item.style.w + space;
                        });
                    }
                }else if (action === 'verticalSpace'){
                    if (actives.length > 1) {
                        let [width,height] = getComputedSize(this.$el);
                        let sumHeight = actives.reduce((sum, item) => sum + item.style.h, 0);
                        let space = (height - sumHeight) / (actives.length - 1);
                        let lastY = 0;
                        actives.forEach((item) => {
                            item.style.y = lastY;
                            lastY = item.style.y + item.style.h + space;
                        });
                    }
                }else if (action === 'moveUp'){
                    actives.forEach(item=>{
                        item.style.z++;
                    })
                }else if (action === 'moveDown'){
                    actives.forEach(item=>{
                        item.style.z = Math.max(0,item.style.z - 1);
                    })
                }else if (action === 'moveTop'){
                    let maxZ = Math.max(...this.Items.map(item=>item.style.z));
                    actives.forEach(item=>{
                        item.style.z = maxZ + 1;
                    })
                }else if (action === 'moveBottom'){
                    actives.forEach(item=>{
                        item.style.z = 0;
                    })
                }
            }
        }
    }
</script>

<style scoped lang="less">

    .freedom-container {
        height: 334px;
        width: 375px;
        position: relative;
        margin: 0 auto;
        user-select: none;
        outline: 1px solid gray;
    }
</style>
